package com.kxj.gaode;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.amap.api.navi.AMapNavi;
import com.amap.api.navi.AMapNaviListener;
import com.amap.api.navi.AMapNaviView;
import com.amap.api.navi.AMapNaviViewListener;
import com.amap.api.navi.enums.NaviType;
import com.amap.api.navi.model.AMapLaneInfo;
import com.amap.api.navi.model.AMapNaviCameraInfo;
import com.amap.api.navi.model.AMapNaviCross;
import com.amap.api.navi.model.AMapNaviInfo;
import com.amap.api.navi.model.AMapNaviLocation;
import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
import com.amap.api.navi.model.AMapServiceAreaInfo;
import com.amap.api.navi.model.AimLessModeCongestionInfo;
import com.amap.api.navi.model.AimLessModeStat;
import com.amap.api.navi.model.NaviInfo;
import com.amap.api.navi.model.NaviLatLng;
import com.autonavi.tbt.TrafficFacilityInfo;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.SynthesizerListener;
import com.xzxy.app.R;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

public class GaodeNaviActivity extends Activity {
	private static final String TAG = "GaodePlugin";
	/**
	 * 导航视图容器
	 */
	private AMapNaviView aMapNaviView;
	/**
	 * 导航视图
	 */
	private AMapNavi aMapNavi;
	/**
	 * 接收从前台传递的所有坐标
	 */
	private List<NaviLatLng> latLngList = new ArrayList<NaviLatLng>();
	/**
	 * 起点坐标
	 */
	private NaviLatLng start = new NaviLatLng();
	/**
	 * 终点坐标
	 */
	private NaviLatLng end = new NaviLatLng();
	/**
	 * 当前的路段，多路段导航时，记录当前的路段
	 */
	private int currentRoute = 0;
	
	/**
	 * 导航模式,1.GPS   2.	EMULATOR
	 */
	private static int naviType=0;
	/**
	 * 讯飞语音的APP_KEY
	 */
	private static final String IFLYTEK_APPKEY = "59055fdf";
	/**
	 * 讯飞语音合成
	 */
	private SpeechSynthesizer speechSynthesizer;
	private LinkedList<String> wordList = new LinkedList();
	private final int TTS_PLAY = 1;
	private final int CHECK_TTS_PLAY = 2;
	private boolean isPlaying = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.gaode_navi_layout);
		naviType=getNaviType();
		aMapNaviView = (AMapNaviView) findViewById(R.id.navi_view);
		aMapNaviView.onCreate(savedInstanceState);
		// 初始化导航坐标
		initNaviLatLngList();
		// 初始化讯飞语音
		SpeechUtility.createUtility(GaodeNaviActivity.this,
				SpeechConstant.APPID + "=" + IFLYTEK_APPKEY);
		if (speechSynthesizer == null) {
			createSynthesizer();
		}
		aMapNaviView.setAMapNaviViewListener(new MyAMapNaviViewListener());

		aMapNavi = AMapNavi.getInstance(getApplicationContext());
		aMapNavi.addAMapNaviListener(new MyAMapNaviListener());

	}
	/**
	 * 从配置文件中读取导航类型
	 * @return
	 */
	private int getNaviType(){
		try {
			ActivityInfo activityInfo=getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
			Bundle bundle=activityInfo.metaData;
			return bundle.getInt("naviType");
		} catch (NameNotFoundException e) {
			e.printStackTrace();
		}
		return 1;
	}

	/**
	 * 初始化坐标集合
	 */
	private void initNaviLatLngList() {
		String jsonString = getIntent().getExtras().get("latLngList")
				.toString();
		try {
			JSONArray jsonArray = new JSONArray(jsonString);
			for (int i = 0; i < jsonArray.length(); i++) {
				JSONObject obj = jsonArray.getJSONObject(i);
				latLngList.add(new NaviLatLng(obj.getDouble("latitude"), obj
						.getDouble("longitude")));
			}
			Log.i(TAG, "initNaviLatLngList--->导航坐标初始化成功，有" + latLngList.size()
					+ "个坐标");
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @author kangxiaojun
	 * @desc 导航视图事件监听。
	 */
	class MyAMapNaviViewListener implements AMapNaviViewListener {

		/**
		 * 是否锁定地图的回调。
		 */
		@Override
		public void onLockMap(boolean isLock) {

		}

		/**
		 * 导航页面左下角返回按钮的回调接口
		 * false-由SDK主动弹出『退出导航』对话框，true-SDK不主动弹出『退出导航对话框』，由用户自定义
		 */
		@Override
		public boolean onNaviBackClick() {
			return false;
		}

		/**
		 * 导航页面左下角返回按钮点击后弹出的『退出导航对话框』中选择『确定』后的回调接口。
		 */
		@Override
		public void onNaviCancel() {
			finish();
		}

		/**
		 * 导航界面地图状态的回调。
		 */
		@Override
		public void onNaviMapMode(int arg0) {

		}

		/**
		 * 界面右下角功能设置按钮的回调接口。
		 */
		@Override
		public void onNaviSetting() {

		}

		/**
		 * 界面左上角转向操作的点击回调。
		 */
		@Override
		public void onNaviTurnClick() {

		}

		/**
		 * 导航view加载完成回调。
		 */
		@Override
		public void onNaviViewLoaded() {
			Log.i(TAG, "AMapNaviViewListener--onNaviViewLoaded--->导航页面加载成功");
		}

		/**
		 * 界面下一道路名称的点击回调。
		 */
		@Override
		public void onNextRoadClick() {

		}

		/**
		 * 界面全览按钮的点击回调。
		 */
		@Override
		public void onScanViewButtonClick() {

		}

	}

	/**
	 * @author kangxiaojun
	 * @desc 导航事件监听
	 */
	class MyAMapNaviListener implements AMapNaviListener {
		/**
		 * 初始化导航失败时回调
		 */
		@Override
		public void onInitNaviFailure() {
			Log.i(TAG, "AMapNaviListener--onInitNaviFailure--->导航初始化失败");
		}

		/**
		 * 计算路线成功时回调(步行，驾车，骑行)
		 */
		@Override
		public void onInitNaviSuccess() {
			Log.i(TAG, "AMapNaviListener--onInitNaviSuccess--->导航初始化成功");
			// 初始化成功，开始计算路线

			start.setLatitude(latLngList.get(currentRoute).getLatitude());
			start.setLongitude(latLngList.get(currentRoute).getLongitude());

			end.setLatitude(latLngList.get(currentRoute + 1).getLatitude());
			end.setLongitude(latLngList.get(currentRoute + 1).getLongitude());
			// aMapNavi.startGPS();
			currentRoute++;
			aMapNavi.calculateWalkRoute(start, end);
		}

		/**
		 * 计算路线失败时回调
		 */
		@Override
		public void onCalculateRouteFailure(int errorInfo) {
			Log.i(TAG,
					"AMapNaviListener--onCalculateRouteSuccess--->计算路线失败,错误信息："
							+ ErrorInfo.getError(errorInfo));
		}

		/**
		 * 计算路线成功时回调(步行，驾车，骑行)
		 */
		@Override
		public void onCalculateRouteSuccess() {
			Log.i(TAG, "AMapNaviListener--onCalculateRouteSuccess--->计算路线成功");
			aMapNavi.startNavi(naviType);
		}

		/**
		 * 启动导航后的回调函数
		 * 
		 * @param tyep
		 *            NaviType.EMULATOR 数值2， 模拟导航 NaviType.GPS 数值1 GPS导航
		 */
		@Override
		public void onStartNavi(int tyep) {
			Log.i(TAG, "AMapNaviListener--onStartNavi--->开始导航");
		}

		/**
		 * 到达目的地后回调函数。
		 */
		@Override
		public void onArriveDestination() {
			Log.i(TAG, "AMapNaviListener--onArriveDestination--->到达目的地");
			if (currentRoute < latLngList.size() - 1) {
				AlertDialog.Builder builder = new AlertDialog.Builder(
						GaodeNaviActivity.this);
				builder.setMessage("去下个点看看");
				builder.setNegativeButton("取消",
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								finish();
							}
						});
				builder.setPositiveButton("去看看",
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								start.setLatitude(latLngList.get(currentRoute)
										.getLatitude());
								start.setLongitude(latLngList.get(currentRoute)
										.getLongitude());

								end.setLatitude(latLngList
										.get(currentRoute + 1).getLatitude());
								end.setLongitude(latLngList.get(
										currentRoute + 1).getLongitude());
								currentRoute++;
								aMapNavi.calculateWalkRoute(start, end);
								aMapNavi.startNavi(NaviType.GPS);
							}
						});
				builder.show();
			} else {
				AlertDialog.Builder builder = new AlertDialog.Builder(
						GaodeNaviActivity.this);
				builder.setMessage("到达目的地，关闭导航");
				builder.setPositiveButton("关闭",
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								finish();
							}
						});
				builder.show();
			}
		}

		/**
		 * 模拟导航停止后回调函数。
		 */
		@Override
		public void onEndEmulatorNavi() {
			Log.i(TAG, "AMapNaviListener--onEndEmulatorNavi--->模拟导航到达目的地");

			if (currentRoute < latLngList.size() - 1) {
				AlertDialog.Builder builder = new AlertDialog.Builder(
						GaodeNaviActivity.this);
				builder.setMessage("去下个点看看");
				builder.setNegativeButton("取消",
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								finish();
							}
						});
				builder.setPositiveButton("去看看",
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								start.setLatitude(latLngList.get(currentRoute)
										.getLatitude());
								start.setLongitude(latLngList.get(currentRoute)
										.getLongitude());

								end.setLatitude(latLngList
										.get(currentRoute + 1).getLatitude());
								end.setLongitude(latLngList.get(
										currentRoute + 1).getLongitude());
								currentRoute++;
								aMapNavi.calculateWalkRoute(start, end);
								aMapNavi.startNavi(NaviType.EMULATOR);
							}
						});
				builder.show();
			} else {
				AlertDialog.Builder builder = new AlertDialog.Builder(
						GaodeNaviActivity.this);
				builder.setMessage("到达目的地，关闭导航");
				builder.setPositiveButton("关闭",
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								finish();
							}
						});
				builder.show();
			}
		}

		/**
		 * 导航播报信息回调函数。
		 */
		@Override
		public void onGetNavigationText(int type, String text) {
			Log.i(TAG, "AMapNaviListener--onGetNavigationText--->导航语音播报："
					+ text);
			if (wordList != null) {
				wordList.addLast(text);
			}
			handler.obtainMessage(CHECK_TTS_PLAY).sendToTarget();
		}

		/**
		 * 巡航模式（无路线规划）下，道路设施信息更新回调，
		 * 已过时，使用OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] arg0)
		 */
		@Override
		public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo arg0) {

		}

		/**
		 * 巡航模式（无路线规划）下，道路设施信息更新回调
		 */
		@Override
		public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] arg0) {

		}

		/**
		 * 巡航模式（无路线规划）下，道路设施信息更新回调，
		 * 已过时，使用OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] arg0)
		 */
		@Override
		public void OnUpdateTrafficFacility(
				@SuppressWarnings("deprecation") TrafficFacilityInfo arg0) {

		}

		/**
		 * 关闭路口放大图时回调
		 */
		@Override
		public void hideCross() {
		}

		/**
		 * 关闭道路信息时回调。
		 */
		@Override
		public void hideLaneInfo() {
		}

		/**
		 * 通知当前是否显示平行路切换
		 * 
		 * @param parallelRoadType
		 *            - 0表示隐藏 1 表示显示主路 2 表示显示辅路
		 */
		@Override
		public void notifyParallelRoad(int parallelRoadType) {
		}

		/**
		 * 驾车路径导航到达某个途经点的回调函数。
		 */
		@Override
		public void onArrivedWayPoint(int arg0) {
		}

		/**
		 * 多路线算路成功回调
		 */
		@Override
		public void onCalculateMultipleRoutesSuccess(int[] arg0) {
		}

		/**
		 * 用户手机GPS设置是否开启的回调函数。
		 * 
		 * @param enabled
		 *            true,开启;false,未开启。
		 */
		@Override
		public void onGpsOpenStatus(boolean enabled) {
		}

		/**
		 * 当GPS位置有更新时的回调函数。
		 * 
		 * @param location
		 *            当前位置的定位信息。
		 */
		@Override
		public void onLocationChange(AMapNaviLocation location) {
		}

		/**
		 * 导航引导信息回调 naviinfo 是导航信息类。
		 */
		@Override
		public void onNaviInfoUpdate(NaviInfo naviinfo) {
		}

		/**
		 * 导航引导信息回调 naviinfo 是导航信息类。已过时，请使用onNaviInfoUpdate(NaviInfo naviinfo)
		 */
		@Override
		public void onNaviInfoUpdated(
				@SuppressWarnings("deprecation") AMapNaviInfo naviinfo) {
		}

		/**
		 * 回调各种类型的提示音，类似高德导航"叮"
		 * 
		 * @param type
		 *            EPlay_NULL 0 无 , EPLay_Reroute 1 偏航重算 , EPlay_Ding 100
		 *            马上到转向路口的时候发的提示音 , EPlay_Dong 101 导航状态下测速电子眼通过音,
		 *            EPlay_Elec_Ding 102 巡航状态下电子眼（所有类型）通过音,
		 */
		@Override
		public void onPlayRing(int type) {

		}

		/**
		 * 驾车导航时，如果前方遇到拥堵时需要重新计算路径的回调。
		 */
		@Override
		public void onReCalculateRouteForTrafficJam() {
			if (wordList != null) {
				wordList.addLast("前方路线拥堵，路线重新规划");
			}
		}

		/**
		 * 步行或驾车导航时,出现偏航后需要重新计算路径的回调函数。
		 */
		@Override
		public void onReCalculateRouteForYaw() {
			if (wordList != null) {
				wordList.addLast("路线重新规划");
			}
		}

		/**
		 * 服务区信息回调函数
		 */
		@Override
		public void onServiceAreaUpdate(AMapServiceAreaInfo[] arg0) {

		}

		/**
		 * 当前方路况光柱信息有更新时回调函数。
		 */
		@Override
		public void onTrafficStatusUpdate() {

		}

		/**
		 * 显示路口放大图回调。
		 */
		@Override
		public void showCross(AMapNaviCross arg0) {

		}

		/**
		 * 显示道路信息回调。
		 * 
		 * @param laneInfos
		 *            道路信息数组，可获得各条道路分别是什么类型，可用于用户使用自己的素材完全自定义显示。
		 * @param laneBackgroundInfo
		 *            道路背景数据数组，可用于装载官方的DriveWayView，并显示。
		 * @param laneRecommendedInfo
		 *            - 道路推荐数据数组，可用于装载官方的DriveWayView，并显示。
		 */
		@Override
		public void showLaneInfo(AMapLaneInfo[] laneInfos,
				byte[] laneBackgroundInfo, byte[] laneRecommendedInfo) {

		}

		/**
		 * 巡航模式（无路线规划）下，统计信息更新回调 当拥堵长度大于500米且拥堵时间大于5分钟时回调
		 */
		@Override
		public void updateAimlessModeCongestionInfo(
				AimLessModeCongestionInfo arg0) {

		}

		/**
		 * 巡航模式（无路线规划）下，统计信息更新回调 连续5个点大于15km/h后开始回调
		 */
		@Override
		public void updateAimlessModeStatistics(AimLessModeStat arg0) {

		}

		/**
		 * 导航过程中的摄像头信息回调函数
		 */
		@Override
		public void updateCameraInfo(AMapNaviCameraInfo[] arg0) {
		}

	}

	/**
	 * 初始化语音合成
	 */
	private void createSynthesizer() {
		speechSynthesizer = SpeechSynthesizer.createSynthesizer(
				GaodeNaviActivity.this, new InitListener() {
					@Override
					public void onInit(int errorcode) {
						if (ErrorCode.SUCCESS == errorcode) {
							Log.i(TAG, "SpeechSynthesizer语音合成初始化成功!");
						} else {
							Log.i(TAG, "SpeechSynthesizer语音合成初始化失败!");
						}
					}
				});
		// 语音合成参数设置，详见《科大讯飞MSC API手册(Android)》SpeechSynthesizer 类
		speechSynthesizer.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");// 设置发音人
		speechSynthesizer.setParameter(SpeechConstant.SPEED, "50");// 设置语速
		speechSynthesizer.setParameter(SpeechConstant.VOLUME, "80");// 设置音量，范围0~100
		speechSynthesizer.setParameter(SpeechConstant.ENGINE_TYPE,
				SpeechConstant.TYPE_CLOUD); // 设置云端
	}

	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
			case TTS_PLAY:
				synchronized (speechSynthesizer) {
					if (!isPlaying && speechSynthesizer != null
							&& wordList.size() > 0) {
						isPlaying = true;
						String playtts = wordList.removeFirst();
						if (speechSynthesizer == null) {
							createSynthesizer();
						}
						speechSynthesizer.startSpeaking(playtts,
								new MySynthesizerListener());
					}
				}
				break;
			case CHECK_TTS_PLAY:
				if (!isPlaying) {
					handler.obtainMessage(1).sendToTarget();
				}
				break;
			}
		}
	};

	class MySynthesizerListener implements SynthesizerListener {
		@Override
		public void onCompleted(SpeechError arg0) {
			isPlaying = false;
			handler.obtainMessage(1).sendToTarget();
		}

		@Override
		public void onEvent(int arg0, int arg1, int arg2, Bundle arg3) {
		}

		@Override
		public void onBufferProgress(int arg0, int arg1, int arg2, String arg3) {
			// 合成进度
			isPlaying = true;
		}

		@Override
		public void onSpeakBegin() {
			// 开始播放
			isPlaying = true;
		}

		@Override
		public void onSpeakPaused() {
		}

		@Override
		public void onSpeakProgress(int arg0, int arg1, int arg2) {
			// 播放进度
			isPlaying = true;
		}

		@Override
		public void onSpeakResumed() {
			// 继续播放
			isPlaying = true;
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		aMapNaviView.onResume();
	}

	@Override
	protected void onPause() {
		super.onPause();
		aMapNaviView.onPause();
		// 仅仅是停止你当前在说的这句话，一会到新的路口还是会再说的
		speechSynthesizer.stopSpeaking();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		aMapNaviView.onDestroy();
		aMapNavi.stopNavi();
		aMapNavi.destroy();
		speechSynthesizer.destroy();
	}

}
